package com.restaurant.application.customer;

import com.google.common.base.Strings;
import com.nebutown.base.ViewSpec;
import com.nebutown.base.data.View;
import com.nebutown.base.data.ViewUpdate;
import com.nebutown.commonunits.dataface.DataModes;
import com.nebutown.commonunits.dataface.EntryTypes;
import com.nebutown.commonunits.dataface.FormShell;
import com.nebutown.commonunits.dataface.definitions.PageForm;
import com.nebutown.commonunits.uidataface.UIDataFace;
import com.nebutown.commonunits.utils.DateTimeUtils;
import com.nebutown.commonunits.utils.SnowFlake;
import com.nebutown.generation.basicdata.StringList;
import com.nebutown.generation.basictype.UID;
import com.restaurant.application.coupon.Coupon;
import com.restaurant.application.customer.support.AbstractCustomer;
import com.restaurant.application.customer.support.CustomerData;
import com.restaurant.application.indexes.consumptionlist.AssistConsumptionList;
import com.restaurant.application.indexes.couponlist.AssistCouponList;
import com.restaurant.application.indexes.customerlist.AssistCustomerList;
import com.restaurant.application.indexes.customerlist.mysql.CustomerListBean;
import com.restaurant.application.indexes.customerlist.mysql.CustomerListCriteria;
import com.restaurant.application.indexes.customerlist.mysql.CustomerListImpl;
import com.restaurant.application.level.Level;
import com.restaurant.application.level.support.LevelData;
import com.restaurant.application.levelset.LevelSet;
import com.restaurant.application.minifacade.data.MainBO;
import com.restaurant.application.minifacade.data.PersonBO;
import com.restaurant.application.qrcode.QrCode;
import com.restaurant.application.util.CommonUtils;
import com.restaurant.application.util.Constant;
import com.restaurant.application.util.WeChatCode;
import com.restaurant.application.util.wx.WXLogin;

import java.util.List;
import java.util.Objects;

/**
 * @author Administrator
 */
public class CustomerImpl extends AbstractCustomer {
    @Override
    public View getFullView() {
        return newCommonTable(DataModes.EDIT);
    }

    @Override
    public View getViewLead(ViewSpec viewSpec) {
        if (ViewSpec.FULLLINE.equals(viewSpec)) {
            return newCommonTable(DataModes.EDIT);
        } else if (ViewSpec.SHORTLINE.equals(viewSpec)) {
            return newCommonTable(DataModes.SHOW);
        }
        return getFullView();
    }

    @Override
    public String init(CustomerData data) {
        String str = getStr(data);
        if (!Strings.isNullOrEmpty(str)) {
            return str;
        }
//        生成客户编号
        long count = getIndex(CustomerListImpl.class).count(" true");
        String number = CommonUtils.getCustomerNumber(TYPE, CHANNEL, count);

//        生成客户二维码
        UID qrUid = createNode(QrCode.class.getName()).getId();
        String qrUrl = WeChatCode.getminiQr(CUSTOMER_NUMBER + number, WXLogin.getAccessToken().getAccess_token());
        getUnit(QrCode.class, qrUid).createQr(qrUrl, getId(), number, 1);

//        用户 id,createTime,number,qrCodeUrl是基元初始化是应该有的，而且也不会更改。
        getData()
                .withId(SnowFlake.findUniqueId())
                .withCreateTime(DateTimeUtils.getCurrentMillisecond())
                .withNumber(number)
                .withState(STATE_NORMAL)
                .withQrCodeUrl(qrUrl)
                .withQrCodeUid(qrUid);

//        检查客户初始化时是否有积分，如果没有则设置成0；
        if (Objects.isNull(data.getUsableScores()) || data.getUsableScores() < 0) {
            getData().withUsableScores(0);
        }
        if (Objects.isNull(data.getTotalScores()) || data.getTotalScores() < 0) {
            getData().withTotalScores(0);
        }

//        获取等级
        getLevel();

//        处理基元其他数据信息
        perfect(data);

//        大表单信息记录
        CustomerListBean bean = getSingleton(AssistCustomerList.class).createBean(getId(), getData());
        if (Objects.nonNull(bean)) {
            getIndex(CustomerListImpl.class).insert(bean);
        }
        return Constant.SUCCESS;
    }

    private void getLevel() {
        UID uid = getSingleton(LevelSet.class).findLevel(getData().getTotalScores());
        LevelData data = getUnit(Level.class, uid).findData();
        getData().withLevel(String.valueOf(data.getMemberLevel())).withLevelName(data.getMemberName());
    }

    private String getStr(CustomerData data) {
        if (Strings.isNullOrEmpty(data.getPhone())) {
            return "手机号不能为空";
        }
        if (Strings.isNullOrEmpty(data.getOpenId())) {
            return "微信ID不能为空";
        }
        return getPhoneIsUsable(data);
    }

    private String getPhoneIsUsable(CustomerData data) {
        if (Objects.nonNull(data) && !Strings.isNullOrEmpty(data.getPhone())) {
            List<CustomerListBean> beans = getIndex(CustomerListImpl.class).search(new CustomerListCriteria().withPhoneEquals(data.getPhone()), null, 1);
            if (beans.size() > 0) {
                if (!Strings.isNullOrEmpty(getData().getPhone())) {
                    if (!Objects.equals(getData().getPhone(), data.getPhone())) {
                        return "该手机号已经有人在使用";
                    }
                }
            }
        }
        return null;
    }

    @Override
    public String update(CustomerData data) {
        String phoneIsUsable = getPhoneIsUsable(data);
        if (!Strings.isNullOrEmpty(phoneIsUsable)) {
            return phoneIsUsable;
        }
        perfect(data);
        return Constant.SUCCESS;
    }

    @Override
    public ViewUpdate modify(CustomerData modify, int[] seq) {
        String msg = update(modify);
        if (!Strings.isNullOrEmpty(msg)) {
            if (!Constant.SUCCESS.equals(msg)) {
                return returnViewCall(buildViewCall(unitPosition(), "showErrorMessage", null, new StringList().addData(msg)));
            }
        }
        return returnPushInContainer(getSingleton(AssistCustomerList.class.getName()).getId(), false);
    }

    @Override
    public ViewUpdate addBlack(int[] seq) {
        perfect(new CustomerData().withState(STATE_BLACK));
        return returnPushInContainer(getSingleton(AssistCustomerList.class.getName()).getId(), false);
    }

    @Override
    public ViewUpdate moveOutBlack(int[] seq) {
        perfect(new CustomerData().withState(STATE_NORMAL));
        return returnPushInContainer(getSingleton(AssistCustomerList.class.getName()).getId(), false);
    }

    @Override
    public void plusScores(int scores) {
        if (scores > 0) {
            int usableScores = scores + (Objects.nonNull(getData().getUsableScores()) ? getData().getUsableScores() : 0);
            int totalScores = scores + (Objects.nonNull(getData().getTotalScores()) ? getData().getTotalScores() : 0);
            UID uid = getSingleton(LevelSet.class).findLevel(totalScores);
            LevelData levelData = getUnit(Level.class, uid).findData();
            getData()
                    .withUsableScores(usableScores)
                    .withTotalScores(totalScores)
                    .withLevel(String.valueOf(levelData.getMemberLevel()))
                    .withLevelName(levelData.getMemberName());
//            更新等级
            getLevel();
        }
    }

    @Override
    public String minusScores(int scores) {
        if (Objects.nonNull(getData().getUsableScores()) && getData().getUsableScores() > 0 && scores > 0 && getData().getUsableScores() >= scores) {
            getData().withUsableScores(getData().getUsableScores() - scores);
            return "success";
        }
        return "积分不足!";
    }

    @Override
    public PersonBO getPersonBO() {
        CustomerData data = getData();
        return new PersonBO().withNickName(data.getNickName()).withGender(data.getGender()).withBirthday(data.getBirthday())
                .withPhone(data.getPhone()).withId(data.getNumber());
    }

    @Override
    public MainBO getMainBO() {
        CustomerData data = getData();
        return new MainBO()
                .withNickName(data.getNickName())
                .withAvatarUrl(data.getAvatarUrl())
                .withLevel(data.getLevel())
                .withLevelName(data.getLevelName())
                .withIntegral(data.getUsableScores())
                .withPersonNumber(data.getNumber())
                .withErCode(data.getQrCodeUrl())
                .withLists(getSingleton(AssistCouponList.class).getMyCardBeanList(getId(), Coupon.STATE_OVERTIME, Coupon.STATE_NOT_USED));
    }

    @Override
    public CustomerData findData() {
        return getData().duplicate();
    }

    private View newCommonTable(DataModes dataModes) {
        PageForm pageForm = newFormShell(dataModes).getForm();
        return getSingleton(UIDataFace.class).newGenericForm(unitPosition(), pageForm);
    }

    private FormShell newFormShell(DataModes dataModes) {
        CustomerData data = getData();
        double totalPrice = getSingleton(AssistConsumptionList.class).getTotal(getId());

        FormShell shell = new FormShell("会员管理/会员信息/", 10, 1);

        boolean editable = false;
        if (DataModes.EDIT.equals(dataModes)) {
            editable = true;
        }
        shell.source(data, dataModes);

        shell.at(0, 0, "姓名")
                .getEntry(CustomerData.FN_REALNAME, data.getRealName())
                .placeHolder("姓名")
                .simpleEntry(EntryTypes.STRING)
                .getContent().setEditable(editable);
        shell.at(1, 0, "性别")
                .getEntry(CustomerData.FN_GENDER, data.getGender())
                .placeHolder("性别")
                .simpleEntry(EntryTypes.STRING)
                .getContent().setEditable(editable);
        shell.at(2, 0, "手机号")
                .getEntry(CustomerData.FN_PHONE, data.getPhone())
                .placeHolder("手机号")
                .simpleEntry(EntryTypes.STRING)
                .getContent().setEditable(editable);
        shell.at(3, 0, "会员编号")
                .getEntry(CustomerData.FN_NUMBER, data.getNumber())
                .placeHolder("会员编号")
                .simpleEntry(EntryTypes.STRING)
                .getContent().setEditable(false);
        shell.at(4, 0, "等级")
                .getEntry(CustomerData.FN_LEVELNAME, data.getLevelName())
                .placeHolder("等级")
                .simpleEntry(EntryTypes.STRING)
                .getContent().setEditable(editable);
        shell.at(5, 0, "创建时间")
                .getEntry(CustomerData.FN_CREATETIME, DateTimeUtils.toTime(data.getCreateTime()))
                .placeHolder("创建时间")
                .simpleEntry(EntryTypes.STRING)
                .getContent().setEditable(editable);
        shell.at(6, 0, "可用积分")
                .getEntry(CustomerData.FN_USABLESCORES, String.valueOf(data.getUsableScores()))
                .placeHolder("可用积分")
                .simpleEntry(EntryTypes.STRING)
                .getContent().setEditable(editable);
        shell.at(7, 0, "历史累计积分")
                .getEntry(CustomerData.FN_TOTALSCORES, String.valueOf(data.getTotalScores()))
                .placeHolder("历史累计积分")
                .simpleEntry(EntryTypes.STRING)
                .getContent().setEditable(editable);
        shell.at(8, 0, "累计消费")
                .getEntry("totalPrice", String.valueOf(totalPrice))
                .placeHolder("累计消费")
                .simpleEntry(EntryTypes.STRING)
                .getContent().setEditable(false);
        shell.at(9, 0, "状态")
                .getEntry(CustomerData.FN_STATE, data.getState())
                .placeHolder("状态")
                .simpleEntry(EntryTypes.STRING)
                .getContent().setEditable(editable);
        if (editable) {
            shell.at(10, 0, "修改").buttonField(getPath(CMD_MODIFY), "", true);
            if (STATE_NORMAL.equals(data.getState())) {
                shell.at(10, 1, "加入黑名单").buttonField(getPath(CMD_ADDBLACK), "", true);
            } else {
                shell.at(10, 1, "解除黑名单").buttonField(getPath(CMD_MOVEOUTBLACK), "", true);
            }
        }
        return shell;
    }

    /**
     * 完善或者不全基元信息
     *
     * @param data CustomerData
     */
    private void perfect(CustomerData data) {
        getData().withModifyTime(DateTimeUtils.getCurrentMillisecond());
        if (!Strings.isNullOrEmpty(data.getAvatarUrl())) {
            getData().withAvatarUrl(data.getAvatarUrl());
        }
        if (!Strings.isNullOrEmpty(data.getNickName())) {
            getData().withNickName(data.getNickName());
        }
        if (!Strings.isNullOrEmpty(data.getRealName())) {
            getData().withRealName(data.getRealName());
        }
        if (!Strings.isNullOrEmpty(data.getGender())) {
            getData().withGender(data.getGender());
        }
        if (!Strings.isNullOrEmpty(data.getBirthday())) {
            getData().withBirthday(data.getBirthday());
        }
        if (!Strings.isNullOrEmpty(data.getLevel())) {
            getData().withLevel(data.getLevel());
        }
        if (!Strings.isNullOrEmpty(data.getLevelName())) {
            getData().withLevelName(data.getLevelName());
        }
        if (!Strings.isNullOrEmpty(data.getOpenId())) {
            getData().withOpenId(data.getOpenId());
        }
        if (!Strings.isNullOrEmpty(data.getPhone())) {
            getData().withPhone(data.getPhone());
        }
        if (Objects.nonNull(data.getUsableScores()) && data.getUsableScores() > 0) {
            getData().withUsableScores(data.getUsableScores());
        }
        if (Objects.nonNull(data.getTotalScores()) && data.getTotalScores() > 0) {
            getData().withTotalScores(data.getTotalScores());
        }
        if (!Strings.isNullOrEmpty(data.getState())) {
            getData().withState(data.getState());
        }
        if (!Strings.isNullOrEmpty(data.getAddress())) {
            getData().withAddress(data.getAddress());
        }
    }

    @Override
    public CustomerListBean getCustomerUidDataForCustomerList(CustomerListBean bean) {
        return getSingleton(AssistCustomerList.class).updateBean(getId(), getData(), bean);
    }
}
